package com.healthcloud.utils;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;

import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * Created by yucl on 2017/10/13.
 */
@Configuration
public class RedisUtils {

    @Autowired
    RedisTemplate redisTemplate;

    /**
     * 获得缓存的基本对象。
     *
     * @param key 缓存键值
     * @return 缓存键值对应的数据
     */
    public <T> T getCacheObject(final String key) {
        ValueOperations<String, T> operation = redisTemplate.opsForValue();
        return operation.get(key);
    }
    /**
     * 删除单个对象
     *
     * @param key
     */
    public void deleteObject(final String key) {
         redisTemplate.delete(key);
    }
    /**
     * 向redis里面添加key-value格式的数据
     *
     * @param key
     *            key
     * @param value
     *            value
     */

    public void set(final String key, final String value, final long exp) {


        redisTemplate.execute(new RedisCallback<Object>() {
            @Override
            public Object doInRedis(RedisConnection connection) throws DataAccessException {
                byte[] key_ = key.getBytes();
                byte[] value_ = value.getBytes();
                connection.set(key_, value_);
                connection.expire(key_, exp);
                return true;
            }
        });
    }

    /**
     * 向redis里面添加key-value格式的数据
     *
     * @param key
     *            key
     * @param value
     *            value
     */

    public void setList(final String key, final List value, final long exp) {

        redisTemplate.opsForList().leftPushAll(key,value);
        redisTemplate.expire(key,exp, TimeUnit.SECONDS);
    }


    public void set(String key, String value) {
        this.set(key, value, 6000);
    }

    public void setList(String key,List value){
        this.setList(key,value,6000);
    }

    public void updateValue(String key, long exp) {
        String value = (String) this.get(key);
        this.set(key, value, exp);
    }

    /**
     * 根据key从redis里面取出value
     *
     * @param key
     *            key
     */
    public String get(final String key) {

        return (String)redisTemplate.execute(new RedisCallback<String>() {
            @Override
            public String doInRedis(RedisConnection connection) throws DataAccessException {

                byte[] keyBytes = key.getBytes();
                byte[] bytes = connection.get(keyBytes);
                String str;
                if (bytes == null) {
                    str = "";
                } else {
                    str = new String(bytes);
                }
                return str;
            }
        });
    }


    /**
     * 根据key从redis里面取出value
     *
     * @param key
     *            key
     */
    public List getList(final String key) {

        return (List)redisTemplate.opsForList().range(key,0,-1);
    }


    public Boolean isEmpty(final String key) {
        return (Boolean)redisTemplate.execute(new RedisCallback<Boolean>() {

            @Override
            public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
                return connection.exists(key.getBytes());
            }
        });
    }

    public Boolean del(final String key) {
        return (Boolean)redisTemplate.execute(new RedisCallback<Boolean>() {

            @Override
            public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
                if (isEmpty(key) == null) {
                    return false;
                } else {
                    connection.del(key.getBytes());
                }
                return true;
            }
        });

    }

    public Long showTime(final String key){
        return (Long)redisTemplate.execute(new RedisCallback<Long>() {

            @Override
            public Long doInRedis(RedisConnection connection) throws DataAccessException {
                if (connection.exists(key.getBytes())) {
                    return connection.ttl(key.getBytes());
                }
                return null;
            }
        });
    }

    public Boolean updateExp(final String key, final long exp){
        return (Boolean) redisTemplate.execute(new RedisCallback<Boolean>() {

            @Override
            public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
                if (connection.exists(key.getBytes())) {
                    connection.expire(key.getBytes(), exp);
                    return true;
                }
                return false;
            }
        });
    }

    public String reSetKey(final String old_key, final String new_key){
        return (String)redisTemplate.execute(new RedisCallback<String>() {

            @Override
            public String doInRedis(RedisConnection connection) throws DataAccessException {
                connection.rename(old_key.getBytes(), new_key.getBytes());
                return null;
            }
        });
    }


}
